home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************************
- *
- * *** HAPPy Pascal Compiler ***
- * ユーザ定義の手続き、関数の呼出処理
- *
- * void calluser(Set fsys, ctp *fcp) ;
- *
- * Copyright (c) H.Asano 1992
- *
- *********************************************************************/
-
- #define EXTERN extern
- #include "pascomp.h"
- #include "pcpcd.h"
-
- extern void expression(Set) ;
- extern void selector(Set,ctp*) ;
- extern ctp *searchid(Set) ;
- extern Set *mkset(Set*,int,...) ;
- extern Set *orset(Set*,Set*);
- extern void enterid(ctp*) ;
- extern ctp *mkctp(char*,enum idclass,stp*,ctp*) ;
- extern void pcerr(int,char*) ;
- extern void insymbol(void) ;
- extern boolean compatible(stp*,stp*) ;
- extern boolean assigncompati(stp*,stp*) ;
- extern int align(stp*,int) ;
- extern void gen0(enum pcdmnc) ;
- extern void gen0t(enum pcdmnc,stp*) ;
- extern void gen1(enum pcdmnc,int) ;
- extern void gen2t(enum pcdmnc, stp*,int,int);
- extern void gencupent(enum pcdmnc,int,int) ;
- extern void genjump(enum pcdmnc,int) ;
- extern void genldc(char,long) ;
- extern void load(void) ;
- extern void loadaddress(void) ;
- extern void checkbounds(stp*,int) ;
- extern void skip(Set) ;
-
- static int pfparm(ctp *) ;
- static int actualparm(Set,ctp*) ;
- static boolean congruity(ctp*,ctp*) ;
-
- /**********************************************/
- /* calluser() : ユーザ定義の手続き・関数の呼出 */
- /**********************************************/
- void calluser(Set fsys,ctp *fcp)
- {
- ctp *nxt ;
- enum idkind lkind ;
- int locpar = 0; /* スタックにのせる引数のサイズ*/
- boolean err126 = false ;
-
- lkind = fcp->n.pf.sd.d.pfkind ; /* actual / formal */
-
- if(lkind == actual) { /* 実手続き、実関数の呼出の時 */
- gen1(iMST,level-fcp->n.pf.sd.d.pflev) ; /* mst 命令 を 生成 */
- nxt = fcp->next ;
- }
- else { /* 仮手続き、仮関数の呼出の時 */
- gen2t(iLOD,nilptr,level-fcp->n.pf.sd.d.pflev,
- fcp->n.pf.sd.d.af.f.levadr) ; /* loda mark */
- gen0(iMSI) ; /* msi */
- nxt = fcp->n.pf.sd.d.af.f.prm ;
- }
-
- if(sy ==lparent) {
- do {
- insymbol() ;
- if(!nxt && !err126) {
- pcerr(126,"") ; /* 実引数と仮引数の数が違う */
- err126 = true ;
- }
- if(nxt &&
- ((nxt->klass==proc) || (nxt->klass==func)))
- locpar += pfparm(nxt) ; /* 関数引数、手続き引数 */
- else /* 値引数、変数引数 */
- locpar += actualparm(fsys,nxt) ;
- locpar = align(parmptr,locpar) ;
-
- if(nxt) nxt = nxt->next ; /* 次の引数 */
-
- } while(sy==comma) ;
-
- if(sy == rparent) insymbol() ;
- else pcerr(4,"") ; /* ) がない */
- }
-
- if(nxt && !err126) pcerr(126,"") ; /* 実引数と仮引数の数が違う */
-
-
- if(lkind == actual) /* 実手続き、実関数の呼出の時 */
- gencupent(iCUP,locpar,fcp->n.pf.sd.d.af.a.pfname);/* cup命令生成*/
- else { /* 仮手続き、仮関数の呼出の時 */
- gen2t(iLOD,nilptr,level-fcp->n.pf.sd.d.pflev,
- fcp->n.pf.sd.d.af.f.adradr) ; /*loda 実行adr */
- gen1(iCUI,locpar) ; /* cui命令生成 */
- }
-
- gattr.typtr = fcp->idtype ; /* 手続き・関数の型 */
- }
-
- /********************************************/
- /* actualparm() : 値、変数パラメータ処理 */
- /********************************************/
- static int actualparm(Set fsys,ctp *fnxt)
- {
- stp *lsp ;
- ctp *lcp ;
- int locpar = 0 ;
- Set ws,ws2 ;
-
- mkset(&ws,comma,rparent,-1) ;
- mkset(&ws2,vars,field,-1) ;
- if(fnxt) { /* 引数がある */
-
- lsp = fnxt->idtype ;
- if(fnxt->n.v.vkind == actual) { /* 値引数の時 */
- expression(ws) ; /* 式の処理 */
- if(!assigncompati(lsp,gattr.typtr)) /* 代入可能性チェック */
- pcerr(155,"") ; /* 代入不可能 */
- if(lsp->form <= power) { /* スカラ、範囲型、ポインタ、集合*/
- load() ; /* load命令 */
- if(lsp->form == power)
- checkbounds(lsp,8) ; /* 集合値の範囲チェック */
- else
- checkbounds(lsp,7) ; /* 順序型の範囲チェック */
- if((lsp == realptr) && /* 宣言がreal型で */
- compatible(gattr.typtr,intptr)) { /* 実引数がintegerの時 */
- gen0(iFLT) ; /* flt命令生成 */
- gattr.typtr = realptr ;
- }
- locpar = lsp->size ; /* スタックに積む引数サイズ計算*/
- }
- else { /* 配列、レコード */
- loadaddress() ; /* loadaddress命令 */
- locpar = parmsize ; /* アドレス分のサイズ */
- }
- }
- else { /* 変数引数の時 */
- if(sy == ident) {
- lcp = searchid(ws2) ; /* 変数、フィールド名から探す */
- insymbol() ;
- selector(ws,lcp) ;
- if(lsp != gattr.typtr) /* 型が違う */
- pcerr(142,"") ; /* 仮引数と実引数の型不一致 */
- loadaddress() ; /* loadaddress命令 */
- locpar = parmsize ; /* アドレス分のサイズ */
- }
- else {
- pcerr(6,"") ; /* 不当な記号が現れた */
- skip(ws) ;
- }
- }
- }
- else expression(ws) ; /* 仮引数がない時、とりあえず
- 実引数を式として処理しておく*/
- return(locpar) ;
- }
-
- /**************************************************/
- /* pfparm() : 手続き名、関数名実パラメータ処理 */
- /**************************************************/
- static int pfparm(ctp *fnxt) /* fnxt:仮引数 */
- {
- ctp *lcp , *lcp1;
- Set ws;
-
- mkset(&ws, func,proc, -1);
- lcp = searchid(ws) ; /* 手続き名、関数名から探す */
- if(lcp->klass != fnxt->klass) /* 引数の種類が違う */
- pcerr(142,"") ; /* 仮引数と実引数の型が不一致 */
- else
- if(lcp->n.pf.pfdeckind == standard)
- (lcp->klass==proc) ? pcerr(174,lcp->name) : pcerr(175,lcp->name);
- /* 標準手続き・関数は実引数駄目*/
- else {
- lcp1 = (lcp->n.pf.sd.d.pfkind==actual)
- ? lcp->next : lcp->n.pf.sd.d.af.f.prm ;
- if(!congruity(lcp1,fnxt->n.pf.sd.d.af.f.prm))
- pcerr(127,lcp->name); /* 同形でない */
- else if(lcp->klass == func)
- if(lcp->idtype != fnxt->idtype)
- pcerr(173,lcp->name) ; /* 関数の結果の型が違う */
- }
-
- if(lcp->n.pf.sd.d.pfkind==actual) {/* 実引数の時 */
- gen1(iBAS,level - lcp->n.pf.sd.d.pflev) ;/* baseアドレスを求める*/
- genjump(iLAP,lcp->n.pf.sd.d.af.a.pfname);/*実行アドレス */
- }
- else { /* 仮引数の時 */
- gen2t(iLOD,nilptr,level - lcp->n.pf.sd.d.pflev,
- lcp->n.pf.sd.d.af.f.levadr) ; /*loda 定義水準*/
- gen2t(iLOD,nilptr,level - lcp->n.pf.sd.d.pflev,
- lcp->n.pf.sd.d.af.f.adradr) ; /*loda 実行adr */
- }
-
- insymbol() ;
- return(2) ; /* 暫定 アドレスサイズ×2を返せば良い */
- }
-
- /******************************************/
- /* congruity() : パラメータの同形チェック */
- /******************************************/
- static boolean congruity(ctp *fcp1,ctp *fcp2)
- {
- while(fcp1 && fcp2) { /* 2つとも引数があれば */
- if(fcp1->klass != fcp2->klass) /* 引数の種類が違う */
- return(false) ;
- if(fcp1->klass == vars) { /* 値、変数の時 */
- if(fcp1->linkno != fcp2->linkno) /* 名前並びの数が違う */
- return(false) ;
- if(fcp1->n.v.vkind != fcp2->n.v.vkind) /* 値、変数の種類が違う */
- return(false) ;
- if(fcp1->idtype != fcp2->idtype) /* 型が違う */
- return(false) ;
- }
- else {
- if(fcp1->klass == func) /* 関数引数の時 */
- if(fcp1->idtype != fcp2->idtype)/* 関数の結果型が違う */
- return(false);
- if(!congruity(fcp1->n.pf.sd.d.af.f.prm, fcp2->n.pf.sd.d.af.f.prm)) return(false) ; /* それぞれの仮引数についてチェック*/
- }
- fcp1 = fcp1->next ;
- fcp2 = fcp2->next ;
- }
- if((!fcp1) && (!fcp2)) return(true) ;/* 両方とも数が同じならOK */
- else return(false);/* 数が違えば NG */
- }